package com.qipay.admin.manager;

import com.qipay.admin.BaseController;
import com.qipay.admin.cp.vo.CpInfoDTO;
import com.qipay.admin.login.AuthPassport;
import com.qipay.admin.manager.vo.OperateLogDTO;
import com.qipay.admin.tags.PageModel;
import com.qipay.admin.utils.CpInfoBuilder;
import com.qipay.baas.model.*;
import com.qipay.cp.CpService;
import com.qipay.cpinfo.service.CpInfoService;
import com.qipay.msg.MessageService;
import com.qipay.operate.service.OperateLogService;
import com.qipay.security.UserDetailsServiceImpl;
import com.qipay.user.entity.UserLevel;
import com.qipay.user.service.UserService;
import com.qipay.utils.Result;
import com.qipay.utils.SignSortMD5Utils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by dong on 2017/9/25.
 */
@RestController
@RequestMapping("/sys")
public class SystemControllers extends BaseController {

    private static Logger logger = LoggerFactory.getLogger(SystemControllers.class);

    @Value("${api.url.host}")
    private String apiHost;
    @Value("${api.response.sign.name}")
    private String apiSigKey;

    @Autowired
    UserService userService;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    CpInfoService cpInfoService;
    @Autowired
    CpService cpService;

    @Autowired
    CpInfoBuilder cpInfoBuilder;

    @Autowired
    MessageService messageService;

    @Autowired
    OperateLogService operateLogService;


    @RequestMapping(value = "/changepwd")
    public ModelAndView changePwd(HttpServletResponse response,
                                  HttpServletRequest request) {
        ModelAndView view = createModelAndView("sys-changepwd");
        return view;
    }

    @RequestMapping(value = "/changepwd-save", method = RequestMethod.POST)
    public Result<String> changePwdSave(
            @RequestParam(value = "oldPwd", required = true) String oldPwd,
            @RequestParam(value = "newPwd", required = true) String newPwd,
            @RequestParam(value = "confirmPwd", required = true) String confirmPwd,
            @AuthenticationPrincipal UserDetailsServiceImpl.LoginUserDetails loginUser) {

        Result<String> resultSample = new Result<String>();
        if (StringUtils.isAnyEmpty(oldPwd, newPwd, confirmPwd)) {
            resultSample.setCode(400);
            resultSample.setMsg("参数错误");
            return resultSample;
        }

        if (!StringUtils.equals(newPwd, confirmPwd)) {
            resultSample.setCode(400);
            resultSample.setMsg("两次密码不一致");
            return resultSample;
        }

        User manager = userService.getByName(loginUser.getUsername());
        if (manager == null) {
            resultSample.setCode(400);
            resultSample.setMsg("原密码错误");
            return resultSample;
        }
        String oldDBPassword = passwordEncoder.encode(oldPwd);
        String newDBPassword = passwordEncoder.encode(newPwd);
        if (!StringUtils.equals(oldDBPassword, manager.getPwd())) {
            resultSample.setCode(400);
            resultSample.setMsg("旧密码不对");
            return resultSample;
        }


        manager.setPwd(newDBPassword);
        userService.updatePassword(loginUser.getId(), newDBPassword);

        resultSample.setCode(200);
        resultSample.setMsg("修改成功");
        return resultSample;
    }

    @AuthPassport(key = "admin")
    @RequestMapping(value = {"/user", "/user/list"}, method = RequestMethod.GET)
    public ModelAndView list(
            @RequestParam(value = "n", required = false, defaultValue = "") String nickname,
            @RequestParam(value = "p", required = false, defaultValue = "1") int p,
            @RequestParam(value = "pz", required = false, defaultValue = "10") int pz
    ) {

        ModelAndView view = createModelAndView("sys-user-list");
        int total = userService.count(nickname).intValue();
        view.addObject("total", total);
        view.addObject("userList", userService.page(nickname, p, pz));
        view.addObject("n", nickname);

        PageModel pageModel = new PageModel();
        pageModel.setPage(p);
        pageModel.setPageSize(pz);
        pageModel.setUrl("");
        if (StringUtils.isNotBlank(nickname)) {
            pageModel.setUrl("?n=" + nickname);
        }
        pageModel.setTotal(total);
        view.addObject("page", pageModel);

        return view;
    }
    @AuthPassport(key="admin")
    @RequestMapping(value = "/user/add", method = RequestMethod.GET)
    public ModelAndView userAdd(){
        return createModelAndView("sys-user-add");
    }

    @AuthPassport(key="admin")
    @RequestMapping(value = "/user/save", method = RequestMethod.POST)
    public Result<String> userSave(
            @RequestParam(value = "oldPwd", required = true) String name,
            @RequestParam(value = "newPwd", required = true) String newPwd,
            @RequestParam(value = "confirmPwd", required = true) String confirmPwd,
            @AuthenticationPrincipal UserDetailsServiceImpl.LoginUserDetails loginUser) {

        Result<String> resultSample = new Result<String>();
        if (StringUtils.isAnyEmpty(name, newPwd, confirmPwd)) {
            resultSample.setCode(400);
            resultSample.setMsg("参数错误");
            return resultSample;
        }

        if (!StringUtils.equals(newPwd, confirmPwd)) {
            resultSample.setCode(400);
            resultSample.setMsg("两次密码不一致");
            return resultSample;
        }

        User manager = userService.getByName(name);
        if (manager != null) {
            resultSample.setCode(400);
            resultSample.setMsg("此用户名称已经存在");
            return resultSample;
        }
        String newDBPassword = passwordEncoder.encode(newPwd);
        manager = new User();
        manager.setName(name);
        manager.setSex((byte) 1);
        manager.setPwd(newDBPassword);
        manager.setLevel(1000);
        manager.setPid(0);

        userService.insert(manager);

        resultSample.setCode(200);
        resultSample.setMsg("添加成功");
        return resultSample;
    }

    @RequestMapping(value = "/changepwd2")
    public ModelAndView changePwd2(HttpServletResponse response,
                                  HttpServletRequest request) {
        ModelAndView view = createModelAndView("sys-changepwd2");
        return view;
    }

    @RequestMapping(value = "/changepwd-save2", method = RequestMethod.POST)
    public Result<String> changePwdSave2(
            @RequestParam(value = "oldPwd", required = true) String oldPwd,
            @RequestParam(value = "newPwd", required = true) String newPwd,
            @RequestParam(value = "confirmPwd", required = true) String confirmPwd,
            @AuthenticationPrincipal UserDetailsServiceImpl.LoginUserDetails loginUser) {

        Result<String> resultSample = new Result<String>();
        if (StringUtils.isAnyEmpty(oldPwd, newPwd, confirmPwd)) {
            resultSample.setCode(400);
            resultSample.setMsg("参数为空");
            return resultSample;
        }

        if (!StringUtils.equals(newPwd, confirmPwd)) {
            resultSample.setCode(400);
            resultSample.setMsg("两次密码不一致");
            return resultSample;
        }

        Cp manager = cpService.getOneById(loginUser.getCpId());
        if (manager == null) {
            resultSample.setCode(400);
            resultSample.setMsg("参数错误.");
            return resultSample;
        }
        if (!StringUtils.equals(oldPwd, manager.getWithdrawPassword())) {
            resultSample.setCode(400);
            resultSample.setMsg("旧密码不对");
            return resultSample;
        }
        cpService.updatePwd(manager.getId(),newPwd);
        resultSample.setCode(200);
        resultSample.setMsg("修改成功");
        return resultSample;
    }

    @RequestMapping(value = {"/user/{cpId:[\\d]+}"}, method = RequestMethod.GET)
    public ModelAndView detailUser(@AuthenticationPrincipal UserDetailsServiceImpl.LoginUserDetails loginUser,
                                   @PathVariable @NotNull Long cpId) {

        ModelAndView view = createModelAndView("sys-my");
        User user = userService.getByName(cpId.toString());
        view.addObject("user", user);
        CpInfo cpInfo = cpInfoService.get(cpId);
        CpInfoDTO dto = new CpInfoDTO();
        if (cpInfo != null) {
            dto = cpInfoBuilder.buildCpInfoCTOByCpInfo(cpInfo, true, true);
            view.addObject("detail", dto);
            return view;
        }
        return new ModelAndView("redirect:/");
    }

    @RequestMapping(value = {"/my"}, method = RequestMethod.GET)
    public ModelAndView detailUserMy(@AuthenticationPrincipal UserDetailsServiceImpl.LoginUserDetails loginUser) {
        if (loginUser.getLevel() == UserLevel.ADMIN) {
            return new ModelAndView("redirect:/");
        }
        return detailUser(loginUser, Long.valueOf(loginUser.getUsername()));
    }

    @AuthPassport(key = "agent")
    @RequestMapping(value = {"/msg"}, method = RequestMethod.GET)
    public ModelAndView listMsgUnread(@AuthenticationPrincipal UserDetailsServiceImpl.LoginUserDetails loginUser,
                                      @RequestParam(value = "p", required = false, defaultValue = "1") int p,
                                      @RequestParam(value = "pz", required = false, defaultValue = "10") int pz,
                                      @RequestParam(value = "t", required = false, defaultValue = "0") byte isread
    ) {
        ModelAndView view = createModelAndView("sys-msg-list");
        boolean isAll = isread == 1;
        List<Message> list = null;
        int total = 0;
        if (isAll) {
            total = (int) messageService.countByReceiveId((int) loginUser.getCpId());
            if (total > 0) {
                list = messageService.selectPageByUid((int) loginUser.getCpId(), p, pz);
            }
        } else {
            list = messageService.selectUnReadByUid((int) loginUser.getCpId());
            total = list != null ? list.size() : 0;
            messageService.updateReadedStatusByUid((int) loginUser.getCpId());
        }

        view.addObject("lst", list);
        view.addObject("total", total);
        PageModel pageModel = new PageModel();
        pageModel.setPage(p);
        pageModel.setPageSize(pz);
        pageModel.setUrl("?t=" + isread);
        pageModel.setTotal(total);
        view.addObject("page", pageModel);
        return view;
    }

    @AuthPassport(key = "admin")
    @RequestMapping(value = {"/log"}, method = RequestMethod.GET)
    public ModelAndView listLog(@AuthenticationPrincipal UserDetailsServiceImpl.LoginUserDetails loginUser,
                                @RequestParam(value = "p", required = false, defaultValue = "1") int p,
                                @RequestParam(value = "pz", required = false, defaultValue = "10") int pz,
                                @RequestParam(value = "t", required = false, defaultValue = "1") String type,
                                @RequestParam(value = "uid", required = false, defaultValue = "") String uidStr
    ) {
        Integer uid = null;
        ModelAndView view = createModelAndView("log-lst");
        if (StringUtils.isNotEmpty(uidStr)) {
            if (uidStr.equals("1")) {
                uidStr = "admin";
            }
            User userFind = userService.getByName(uidStr);
            if (userFind == null) {
                view.addObject("page", new PageModel());
                return view;
            }
            uid = userFind.getId();
        }

        List<OperateLogDTO> list = null;
        String dbType = type.equalsIgnoreCase("1") ? "" : type;
        Long total = operateLogService.countLogByUrlAndType(uid, dbType);
        List<OperateLog> dbList = null;
        if (total != null && total.longValue() > 0) {
            dbList = operateLogService.selectLogByUrlAndType(uid, dbType, p, pz);
            if (dbList != null) {
                list = new ArrayList<>(dbList.size());
                for (OperateLog db : dbList
                        ) {
                    Integer id = db.getUserId();
                    OperateLogDTO dto = new OperateLogDTO();
                    BeanUtils.copyProperties(db, dto);
                    if (id != null && id.intValue() > 0) {
                        User user = userService.getByPK(id);
                        if (user != null) {
                            dto.setUserCpId(user.getName());
                        }
                    }
                    list.add(dto);
                }
            }
        }

        view.addObject("lst", list);
        view.addObject("total", total);
        PageModel pageModel = new PageModel();
        pageModel.setPage(p);
        pageModel.setPageSize(pz);
        pageModel.setUrl("?t=" + type + "&uid=" + (uid != null ? uid.toString() : ""));
        pageModel.setTotal(total);
        view.addObject("page", pageModel);
        return view;
    }

    @RequestMapping(value = {"/qrcode"}, method = RequestMethod.GET)
    public ModelAndView qrcode(@AuthenticationPrincipal UserDetailsServiceImpl.LoginUserDetails loginUser) {
        if (loginUser.getLevel() == UserLevel.ADMIN) {
            return new ModelAndView("redirect:/");
        }
        ModelAndView view = createModelAndView("qrcode");
        long cpId = loginUser.getCpId();
        Cp cp = cpService.getOneById(cpId);
        if (cp != null) {
            view.addObject("host", apiHost + "common/qrcode?content=");
            String url = apiHost + "common/cp/pay/qrcode?mchid=%s&sign=%s";
            Map<String, Object> params = new HashMap<>(2);
            params.put("mchid", cp.getAppId());
            String mySign = SignSortMD5Utils.getSign(params, cp.getSecretId(), apiSigKey);
            url = String.format(url, cp.getAppId(), mySign);
            view.addObject("url", url);
        }
        return view;
    }
}
